package com.li.config;


import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class RabbitmqConfig {
    @Autowired
    private RabbitProperties rabbitProperties;

    // ------------交换机------------------------
    public static final String amqDirectExchange = "amq.direct";

    // ------------业务-routingKey------------------------
    public static final String businessRoutingKey = "business.message.routing.key";

    // ------------死信-routingKey------------------------
    public static final String dlRoutingKey = "dl.message.routing.key";

    // ------------业务队列------------------------
    public static final String businessQueue = "business.queue";

    // ------------死信队列------------------------
    public static final String dlQueue = "dl.queue";


    @Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(rabbitProperties.getHost());
        connectionFactory.setUsername(rabbitProperties.getUsername());
        connectionFactory.setPassword(rabbitProperties.getPassword());
        connectionFactory.setVirtualHost(rabbitProperties.getVirtualHost());
        connectionFactory.setPort(rabbitProperties.getPort());
        return connectionFactory;
    }

    @Bean
    public RabbitAdmin amqpAdmin() {
        return new RabbitAdmin(connectionFactory());
    }

    @Bean
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory());
        rabbitTemplate.setMessageConverter(jackson2JsonMessageConverter());
        return rabbitTemplate;
    }

    @Bean
    public MessageConverter jackson2JsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }


    //申明交换机
    @Bean
    public DirectExchange amqDirectExchange() {
        return new DirectExchange(amqDirectExchange);
    }

    //业务队列
    @Bean
    public Queue businessQueue() {
        Map<String, Object> params = new HashMap<>();
        //设置队列的过期时间
        params.put("x-message-ttl", 6000);
        //声明当前队列绑定的死信交换机
        params.put("x-dead-letter-exchange", amqDirectExchange);
        //声明当前队列的死信路由键
        params.put("x-dead-letter-routing-key", dlRoutingKey);
        // 第一个参数是创建的queue的名字，第二个参数是是否支持持久化
        return new Queue(businessQueue, true, true, false, params);
    }

    //死信队列
    @Bean
    public Queue dlQueue() {
        return new Queue(dlQueue, true, true, false);
    }

    //业务队列路由绑定
    @Bean
    public Binding businessBinding() {
        //链式写法: 用指定的路由键将队列绑定到交换机
        return BindingBuilder.bind(businessQueue()).to(amqDirectExchange()).with(businessRoutingKey);
    }

    //死信队列路由绑定
    @Bean
    public Binding dlBinding() {
        //链式写法: 用指定的路由键将队列绑定到交换机
        return BindingBuilder.bind(dlQueue()).to(amqDirectExchange()).with(dlRoutingKey);
    }
}
